<!-- App.vue -->
<template>
  <div class="container">
    <h1>📄 AI 智能分析系统</h1>
    <!-- 输入区域 -->
    <div class="input-section">
      <textarea
          v-model="inputText"
          placeholder="请输入医疗质量数据..."
          rows="6"
          class="text-input"
      ></textarea>
      <div>
      </div>
      <div>
        <label class="text-style" for="dropdown">请选择一个选项：</label>
        <select id="dropdown" v-model="selectedValue">
          <option value="{APPID}">请选择</option>
          <option value="9c8cdc23a81e48cc9979e9543ac06c4f">医疗质量与安全维度</option>
          <option value="a6248bff9b9c4f0d819bc0e90adb3629">DRG分组规划</option>
          <option value="f517943fe1ca4afa9d4b0e7f10172b34">运营效率监控维度</option>
          <option value="8ee6a940ac4e4ec4bf0c41554b08a62f">DRG与财务分析维度</option>
        </select>
        <h3 class="text-style">调用AI URL：<a :href="API_URL">{{ API_URL }}</a></h3>
      </div>

      <button @click="startStream" :disabled="isStreaming" class="send-btn">
        {{ isStreaming ? '分析中...' : '生成报告' }}
      </button>
    </div>

    <!-- 输出区域 -->
    <div class="output-section">
      <h3>📊 分析结果：</h3>
      <div ref="outputRef" class="response-box">
        <!-- 渲染富文本内容 -->
        <div class="ai-response-content" v-html="renderedHTML"></div>
        <!-- 打字光标 -->
        <span v-if="isStreaming" class="cursor">|</span>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, nextTick,computed } from 'vue'
import MarkdownIt from 'markdown-it'
import DOMPurify from 'dompurify'

// ==================== 配置区 ====================

// 基础 URL
//医疗质量与安全维度
//const API_URL = 'https://dashscope.aliyuncs.com/api/v2/apps/agent/9c8cdc23a81e48cc9979e9543ac06c4f/compatible-mode/v1/responses'
//DRG分组规划
//const API_URL = 'https://dashscope.aliyuncs.com/api/v2/apps/agent/a6248bff9b9c4f0d819bc0e90adb3629/compatible-mode/v1/responses'
//运营效率监控维度
//const API_URL = 'https://dashscope.aliyuncs.com/api/v2/apps/agent/f517943fe1ca4afa9d4b0e7f10172b34/compatible-mode/v1/responses'
//DRG与财务分析维度
//const API_URL = 'https://dashscope.aliyuncs.com/api/v2/apps/agent/8ee6a940ac4e4ec4bf0c41554b08a62f/compatible-mode/v1/responses'

//console.log('selectedApi :'+ selectedApi.value)
const API_KEY = 'sk-69a5314907eb4feea7c1a371c6778a51' // ⚠️ 替换为你自己的有效 Key

// ==================== 响应式数据 ====================
const inputText = ref(``)
const isStreaming = ref(false)
const renderedHTML = ref('')
const outputRef = ref(null)

// 定义下拉选项的值
const selectedValue = ref('{APPID}'); // 默认值为空

// 计算生成的 URL
const API_URL = computed(() => {
  const base = 'https://dashscope.aliyuncs.com/api/v2/apps/agent/APPID/compatible-mode/v1/responses';
  return base.replace('APPID', selectedValue.value);
});

// ==================== 初始化 markdown-it（含表格修复插件）====================
const md = new MarkdownIt({
  html: false,
  breaks: true,
  typographer: true
})

// 🔧 插件：检测并转换“空格分隔”的纯文本表格为 Markdown 表格
function detectAndConvertTextTable(text) {
  const lines = text.trim().split('\n')
  let headers = []
  let rows = []

  for (const line of lines) {
    const trimmed = line.trim()
    if (!trimmed) continue

    // 使用多个空格或制表符分割
    const cells = trimmed.split(/\s{2,}|\t/).filter(Boolean)
    if (cells.length < 2) continue // 至少两列

    // 判断是否为表头：不含明显数字/百分比
    const hasNumbers = /[\d\.]+%?/.test(trimmed)
    if (!headers.length && !hasNumbers) {
      headers = cells
    } else if (hasNumbers && cells.length >= headers.length) {
      // 数据行：补全或截断以匹配表头长度
      const row = cells.slice(0, headers.length)
      rows.push(row)
    }
  }

  // 构造 Markdown 表格
  if (headers.length >= 2 && rows.length >= 1) {
    const headerRow = '| ' + headers.join(' | ') + ' |'
    const separatorRow = '| ' + headers.map(() => '---').join(' | ') + ' |'
    const dataRows = rows.map(row => '| ' + row.join(' | ') + ' |').join('\n')
    return [headerRow, separatorRow, dataRows].join('\n')
  }

  return null
}

// ✅ 增强 render 方法：自动修复文本表格
const originalRender = md.render.bind(md)
md.render = function (content) {
  let enhancedContent = content

  // 查找可能的表格块（连续多行，每行有多个空格）
  const potentialBlocks = enhancedContent.match(/(?:^|\n)(?:[^\n]+\s+[^\n]+\n?)+/g)
  if (potentialBlocks) {
    potentialBlocks.forEach(block => {
      const cleanedBlock = block.trim()
      if (!cleanedBlock || cleanedBlock.startsWith('|') || cleanedBlock.includes('---')) return

      const tableMarkdown = detectAndConvertTextTable(cleanedBlock)
      if (tableMarkdown) {
        enhancedContent = enhancedContent.replace(cleanedBlock, tableMarkdown)
      }
    })
  }

  try {
    return originalRender(enhancedContent)
  } catch (e) {
    console.error('[Markdown] 渲染失败:', e)
    return `<p style="color:red">❌ 内容渲染错误</p>`
  }
}

// ==================== 流式请求 ====================
const startStream = async () => {
  if (!inputText.value.trim() || isStreaming.value) return

  renderedHTML.value = ''
  isStreaming.value = true
  let accumulatedText = ''

  try {
    const payload = {
      input: [
        {
          type: 'message',
          role: 'user',
          content: [
            {
              type: 'input_text',
              text: inputText.value.trim()
            }
          ]
        }
      ],
      stream: true
    }
    console.log('API_URL :'+ API_URL.value)
    console.log('API_KEY :'+ API_KEY)
    const response = await fetch(API_URL.value, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${API_KEY}`
      },
      body: JSON.stringify(payload)
    })

    if (!response.ok) throw new Error(`HTTP ${response.status}: ${await response.text()}`)

    const reader = response.body.getReader()
    const decoder = new TextDecoder('utf-8')
    let buffer = ''

    while (true) {
      const { done, value } = await reader.read()
      if (done) break

      buffer += decoder.decode(value, { stream: true })
      const lines = buffer.split('\n')
      buffer = lines.pop()

      for (const line of lines) {
        const trimmed = line.trim()
        if (!trimmed.startsWith('data:')) continue

        const dataStr = trimmed.slice(5).trim()
        if (!dataStr || dataStr === '[DONE]') continue

        try {
          const data = JSON.parse(dataStr)
          if (data.type === 'response.output_text.delta' && typeof data.delta === 'string') {
            //const deltaText = data.delta.replace(/<br>/g, '')
            const deltaText = data.delta
            accumulatedText += deltaText
            console.log(data.delta)

            // 使用增强版 markdown-it 渲染（含表格修复）
            const unsafeHtml = md.render(accumulatedText)
            renderedHTML.value = DOMPurify.sanitize(unsafeHtml)

            // 自动滚动到底部
            await nextTick()
            outputRef.value?.scrollTo?.(0, outputRef.value.scrollHeight)
          }
        } catch (err) {
          console.warn('[解析失败]', err, dataStr)
        }
      }
    }

    // 结束标记
    const finalText = accumulatedText + '\n\n✅ 报告生成完成。'
    const unsafeHtml = md.render(finalText)
    renderedHTML.value = DOMPurify.sanitize(unsafeHtml)
  } catch (error) {
    console.error('[请求失败]', error)
    renderedHTML.value = `<span style="color:red">❌ 请求失败：${error.message}</span>`
  } finally {
    isStreaming.value = false
  }
}
</script>

<style scoped>
.container {
  max-width: 960px;
  margin: 0 auto;
  padding: 20px;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  background-color: #f7f9fc;
  min-height: 100vh;
}

h1 {
  text-align: center;
  color: #1a3b6d;
  margin-bottom: 30px;
  font-weight: 600;
}

.input-section {
  margin-bottom: 30px;
}

.text-input {
  width: 100%;
  padding: 14px;
  border: 1px solid #ddd;
  border-radius: 8px;
  font-size: 15px;
  resize: vertical;
  background-color: #fff;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
  transition: border-color 0.3s;
}

.text-input:focus {
  outline: none;
  border-color: #007bff;
}

.send-btn {
  margin-top: 10px;
  padding: 12px 24px;
  background-color: #007bff;
  color: white;
  border: none;
  border-radius: 6px;
  font-size: 16px;
  cursor: pointer;
  transition: background-color 0.3s;
}

.send-btn:hover:not(:disabled) {
  background-color: #0056b3;
}

.send-btn:disabled {
  background-color: #6c757d;
}

.output-section h3 {
  color: #2c3e50;
  margin-bottom: 10px;
}

.response-box {
  width: 100%;
  height: 500px;
  border: 1px solid #080000;
  border-radius: 8px;
  padding: 16px;
  background-color: #fdfdfd;
  overflow-y: auto;
  line-height: 1.7;
  font-size: 15px;
  color: #333;
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1);
}

/* ==================== 富文本样式 ==================== */
.ai-response-content h1,
.ai-response-content h2,
.ai-response-content h3 {
  margin: 1em 0 0.5em;
  color: #07173b;
}

.ai-response-content h1 {
  font-size: 1.8em;
  text-align: center;
}

.ai-response-content h2 {
  font-size: 1.5em;
  border-left: 4px solid #007bff;
  padding-left: 12px;
}

.ai-response-content h3 {
  font-size: 1.3em;
  color: #34495e;
}

:global(.ai-response-content table) {
  width: 100%;
  border-collapse: collapse;
  margin: 1em 0;
  font-size: 0.95em;
  border: 1px solid #2c2a2a;
}

:global(.ai-response-content th,
.ai-response-content td ){
  border: 1px solid #ccc;
  padding: 8px 12px;
  text-align: center;
}

:global(.ai-response-content th ){
  background-color: #f0f5ff;
  font-weight: 600;
  color: #1a3b6d;
}

:global(.ai-response-content tr:nth-child(even) ){
  background-color: #f9f9f9;
}

:global(.ai-response-content p){
  margin: 0.6em 2;
}

:global(.ai-response-content ul) {
  margin-left: 40px;
  margin: 0.6em 1;
  padding-left: 1;
}

:global(.ai-response-content ol) {
  margin-left: 40px;
  margin: 0.6em 2;
  padding-left: 2;
}

:global(.ai-response-content li ){
  margin: 0.6em 1.2;
  padding-left: 20px;
}

.cursor {
  animation: blink 1.2s step-end infinite;
  color: #007bff;
  font-weight: bold;
  font-size: 1.1em;
}

:global(.ai-message table ){
  width: 100%;
  border-collapse: collapse;
  margin: 1em 0;
  font-size: 0.95em;
}

:global(.ai-message th,
.ai-message td ){
  border: 1px solid #ccc;
  padding: 6px 10px;
  text-align: left;
}

:global(.ai-message th ){
  background-color: #f0f5ff;
  font-weight: 600;
}

:global(.ai-message tr:nth-child(even) ){
  background-color: #f9f9f9;
}

@keyframes blink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0; }
}

.text-style {
  color: #080101;
  font-size: 16px;
  font-family: "Microsoft Yahei", sans-serif;
}
</style>